package com.conan.dailyflickr.app;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.conan.dailyflickr.activity.DailyFlickrWidget;

import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import android.webkit.JsPromptResult;

public class PhotoDailyInfo {
	public static final String TAG = "PhotoDailyInfo";
	private Uri.Builder mUrl;  
	static final public int PER_PAGE = 15;
	static final public int PAGES_NUMBER = 1;
	
    private static final String RESPONSE_TAG_PHOTOS = "photos";
    private static final String RESPONSE_ATTR_PAGE = "page";
    private static final String RESPONSE_ATTR_PAGES = "pages";
    private static final String RESPONSE_ATTR_PERPAGE = "perpage";
    private static final String RESPONSE_ATTR_TOTALPAGE = "total";
    
    public static final String RESPONSE_TAG_PHOTO = "photo";
    public static final String RESPONSE_ATTR_ID = "id";
    public static final String RESPONSE_ATTR_SECRET = "secret";
    public static final String RESPONSE_ATTR_SERVER = "server";
    public static final String RESPONSE_ATTR_FARM = "farm";
    public static final String RESPONSE_ATTR_TITLE = "title";
    public static final String RESPONSE_ATTR_DATE_TAKEN = "datetaken"; 
    public static final String RESPONSE_TAG_STATE = "stat";
    public static final String RESPONSE_ATTR_STATE_OK = "ok";
    public static final String RESPONSE_TAG_MESSAGE = "message";
    
	private FlickrApiHelper mFlickrApi;
	
	private PhotoList mPhotoList;
	
	private Context mContext;
	
	public PhotoDailyInfo(Context context) {
		mContext = context;
		
		mFlickrApi = FlickrApiHelper.getInstance();
		
		mUrl = mFlickrApi.buildInterestingURI();
		
		mPhotoList = new PhotoList();
		// the first time get data
		// updateDataFromFlickr(0);
	}
	
	public PhotoDailyInfo(Context context, PhotoList photos, int current, int pageTo, int pages) {
		mContext = context;
		
		mFlickrApi = FlickrApiHelper.getInstance();
		
		mUrl = mFlickrApi.buildInterestingURI();
		
		if(photos != null){
			mPhotoList = photos;
		}else{
			mPhotoList = new PhotoList();
		}
		
		// the first time get data
		// updateDataFromFlickr(0);
	}
	
	
	/**
	 * api_key (Required)
		    Your API application key. See here for more details.
		date (Optional)
		    A specific date, formatted as YYYY-MM-DD, to return interesting photos for.
		extras (Optional)
		    A comma-delimited list of extra information to fetch for each returned record. Currently supported fields are: description, license, date_upload, date_taken, owner_name, icon_server, original_format, last_update, geo, tags, machine_tags, o_dims, views, media, path_alias, url_sq, url_t, url_s, url_m, url_z, url_l, url_o
		per_page (Optional)
		    Number of photos to return per page. If this argument is omitted, it defaults to 100. The maximum allowed value is 500.
		page (Optional)
		    The page of results to return. If this argument is omitted, it defaults to 1. 
	 */
	public boolean updateDataFromFlickr(int page, Date date){
		
		try {
			// JSONObject jSONObject = mFlickrApi.flickrPhotoApi(updateUrl);
			JSONObject jSONObject = mFlickrApi.flickrPhotoApiHttp(page, PER_PAGE, date);
			if(jSONObject == null) return false;
			
			Log.e(TAG, jSONObject.toString());
		
			String message = "fail";
			try {
				message = jSONObject.getString(RESPONSE_TAG_STATE);				
			}catch (JSONException e) {
				e.printStackTrace();
			} 
			
			if(RESPONSE_ATTR_STATE_OK.compareTo(message) != 0) {
				return false;
			}
			
			parsePhotos(jSONObject, mPhotoList);
			

		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} catch (JSONException e) {
			e.printStackTrace();
			return false;
		}
		
		return true;
	}
	
	public PhotoList getPhotoList(){
		return mPhotoList;
	}

    /**
     * @author @le.nguyen
    	 *  TODO
         *  @param @param jSonParser
         *  @param @param photos
         *  @param @return
         *  
         *  @see 
         *  <photos page="2" pages="89" perpage="10" total="881">
		 *			<photo id="2636" owner="47058503995@N01" 
		 *					secret="a123456" server="2" title="test_04"
		 *					ispublic="1" isfriend="0" isfamily="0" />
		 *	<photos>
     */
    private int parsePhotos(JSONObject jSonParser, PhotoList photos){
    	//jSonParser.
    	if(jSonParser == null) return 0;
			
		//inner Json object
        JSONObject jSONObjectInner;
		try {
			jSONObjectInner = jSonParser.getJSONObject(RESPONSE_TAG_PHOTOS);
	        
	        photos.setValues(jSONObjectInner.getInt(RESPONSE_ATTR_PAGES), 
	        		jSONObjectInner.getInt(RESPONSE_ATTR_PAGE));
			// inner array of photos
	        JSONArray photoArray = jSONObjectInner.getJSONArray(RESPONSE_TAG_PHOTO); 
	        //get one random photo from array
	        SimpleDateFormat parseFormat = null;
			SimpleDateFormat outputFormat = null;
	        int total = photoArray.length();
	        Log.w(TAG, "[parse photo][total] = " + total );
	        photos.clear();
	        for(int i= 0; i < total; i++){	        	
	        	// Log.i(TAG, "add photo");
	        	JSONObject jSONPhoto = photoArray.getJSONObject(i);
	        	
	        	final Photo photo = new Photo();
	        	photo.mId = jSONPhoto.getString(RESPONSE_ATTR_ID);
		        photo.mSecret = jSONPhoto.getString(RESPONSE_ATTR_SECRET);
		        photo.mServer = jSONPhoto.getString(RESPONSE_ATTR_SERVER);
		        photo.mFarm = jSONPhoto.getString(RESPONSE_ATTR_FARM);
		        photo.mTitle = jSONPhoto.getString(RESPONSE_ATTR_TITLE);
		        photo.mDate = jSONPhoto.getString(RESPONSE_ATTR_DATE_TAKEN);
		
		        if (parseFormat == null) {
		            parseFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		            outputFormat = new SimpleDateFormat("MMMM d, yyyy");
		        }
		        
		        try {
					photo.mDate = outputFormat.format(parseFormat.parse(photo.mDate));
		        } catch (java.text.ParseException e) {
		            Log.w(TAG, "Could not parse photo date", e);
		        }
		       //  Log.w(TAG, i + ".[mId] = " + photo.mId + " - " + photo.mTitle);
		        
		        ContentValues values = new ContentValues();
		        values.put(PhotoDailyInfo.RESPONSE_ATTR_ID, photo.mId);
		        values.put(PhotoDailyInfo.RESPONSE_ATTR_SECRET,  photo.mSecret);
		        values.put(PhotoDailyInfo.RESPONSE_ATTR_SERVER, photo.mServer );
		        values.put(PhotoDailyInfo.RESPONSE_ATTR_FARM, photo.mFarm);
		        values.put(PhotoDailyInfo.RESPONSE_ATTR_TITLE, photo.mTitle);
		        values.put(PhotoDailyInfo.RESPONSE_ATTR_DATE_TAKEN, photo.mDate);
		                
		        /*Uri uri = */ // mContext.getContentResolver().insert(
		        //						DailyFlickr.CONTENT_URI, values);
		        
		        // Log.d(TAG, photo.getUrl(PhotoSize.SMALL));
		        photos.add(photo);	        	
	        }
	        Log.w(TAG, "[parse photo][done] = " + photos.getCount());;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
       		
    	return photos.getCount();
    }

    /********************************************************************************
     ****************		PhotoList	********************************************
     * A list of {@link com.google.android.photostream.Flickr.Photo photos}.
     * The page index and the page count both depend on the number of photos per page.
     */
	
	public static class PhotoList{
		private ArrayList<Photo> mPhotos = new ArrayList<Photo>();
		private int mCurrent;
		private int mTotals;		
					
		public void add(Photo photo){
			mPhotos.add(photo);
		}
		
		public void clear(){
			mPhotos.clear();
		}
		
		public Photo remove(int index){
			return mPhotos.remove(index);
		}
		
		public Photo get(int index){
			return mPhotos.get(index);
		}
		
        public int getCount() {
            return mPhotos.size();
        }

        public int getPage() {
            return mCurrent;
        }
        
        public void setPage(int page){
        	mCurrent = page;
        }

        public int getTotalPage() {
            return mTotals;
        }        

         public int getPublicPage(){
        	return mCurrent;
        }
        
        public void setValues(int totalPage, int currentPage){
        	mTotals = totalPage;
        	mCurrent = currentPage;
        }
	}
	
	 /*********************************************************************************
     * ***************		Photo			******************************************
     * A photo is represented by a title, the date at which it was taken and a URL.
     * The URL depends on the desired {@link com.google.android.photostream.Flickr.PhotoSize}.
     */
	private static final String PHOTO_IMAGE_URL = "http://farm%s.static.flickr.com/%s/%s_%s%s.jpg";
	public static class Photo implements Parcelable{
		private String mId;
		private String mSecret;
		private String mServer;
		private String mFarm;
		private String mTitle;
		private String mDate;
		public boolean loaded = false;
		
		public Photo() {
		}
		
		public Photo(Parcel in) {
			mId = in.readString();
			mSecret = in.readString();
			mServer = in.readString();
			mFarm = in.readString();
			mTitle = in.readString();
			mDate = in.readString();
		}
		
		public String getTitle(){
			return mTitle;
		}
		
		public String getDate(){
			return mDate;
		}
		
		/**
		 * @see com.google.android.photostream.Flickr.PhotoSize
         */
		public String getUrl(PhotoSize photoSize) {
            return String.format(PHOTO_IMAGE_URL, mFarm, mServer, mId, mSecret, photoSize.size());
        }
		/* (non-Javadoc)
		 * @see android.os.Parcelable#describeContents()
		 */
		@Override
		public int describeContents() {
			return 0;
		}
		
		/* (non-Javadoc)
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {
			return mTitle + ", " + mDate + " @" + mId;
		}
		/* (non-Javadoc)
		 * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
		 */
		@Override
		public void writeToParcel(Parcel dest, int flags) {
			 dest.writeString(mId);
            dest.writeString(mSecret);
            dest.writeString(mServer);
            dest.writeString(mFarm);
            dest.writeString(mTitle);
            dest.writeString(mDate);
		}
		
		public static final Parcelable.Creator<Photo> CREATOR = new Parcelable.Creator<Photo>() {
			
			public Photo createFromParcel(Parcel in){
				return new Photo(in);
			}
			
			public Photo[] newArray(int size){
				return new Photo[size];
			}
		};
	}
	
	public enum PhotoSize {
	        /** Small square image (75x75 px).  */
	        SMALL_SQUARE("_s", 75),
	        
	        /** Thumbnail image (the longest side measures 100 px).	*/
	        THUMBNAIL("_t", 100),
	        
	        /** Small image (the longest side measures 240 px).	*/
	        SMALL("_m", 240),
	        
	        /** Medium image (the longest side measures 500 px).	*/
	        MEDIUM("", 500),
	        
	        /** Large image (the longest side measures 1024 px).    */
	        LARGE("_b", 1024);
	        
	        private final String mSize;
	        private final int mLongSide;

	        private PhotoSize(String size, int longSide) {
	            mSize = size;
	            mLongSide = longSide;
	        }

	        /**
	         * Returns the size in pixels of the longest side of the image.
	         * @return the dimension in pixels of the longest side.
	         */
	        int longSide() {
	            return mLongSide;
	        }

	        /**
	         * Returns the name of the size, as defined by Flickr. For instance,
	         * the LARGE size is defined by the String "_b".
	         *
	         * @return
	         */
	        String size() {
	            return mSize;
	        }

	        @Override
	        public String toString() {
	            return name() + ", longSide=" + mLongSide;
	        }
	 }
}
